package algo.LocalSearch;

import algo.Model.VarInt;
import algo.Model.BasicLocalSearchEntity;
import java.util.Vector;
import java.util.HashSet;
import java.util.Iterator;

public class ConstraintSystem extends BasicLocalSearchEntity implements IConstraint {

	private Vector<IConstraint> _S;
	BasicLocalSearchEntity[]	_Se;
	private int _violations;
	VarInt[]	_vars;
	
	public ConstraintSystem(){
		_S = new Vector<IConstraint>();
	}
	public ConstraintSystem(LocalSolver ls){
		super(ls);
		_S = new Vector<IConstraint>();
		getLocalSolver().post(this);
	}

	public BasicLocalSearchEntity[] getDependEntities(){
		return _Se;
	}
	
	public String name(){
		return "ConstraintSystem[" + getID() + "]";
	}
	
	public VarInt[] getVariables(){ return _vars;}
	
	@Override
	
	public int violations() {
		// TODO Auto-generated method stub
		return _violations;
	}

	@Override
	public int getAssignDelta(VarInt x, int val) {
		// TODO Auto-generated method stub
		int d = 0;
		for(int i = 0; i < _S.size(); i++)
			d = d + _S.elementAt(i).getAssignDelta(x, val);
		return d;
	}

	@Override
	public void propagateInt(VarInt x, int val) {
		// TODO Auto-generated method stub
		_violations = 0;
		for(int i = 0; i < _S.size(); i++){
			//_S.elementAt(i).propagate(x, val); these propagation have already triggered
			_violations += _S.elementAt(i).violations();
		}
	}

	@Override
	public void initPropagate() {
		// TODO Auto-generated method stub
		_violations = 0;
		for(int i = 0; i < _S.size(); i++){
			_S.elementAt(i).initPropagate();
			_violations += _S.elementAt(i).violations();
		}
	}

	public void close(){
		HashSet<VarInt> V = new HashSet<VarInt>();
		_Se = new BasicLocalSearchEntity[_S.size()];
		
		for(int i = 0; i < _S.size(); i++){
			IConstraint c = _S.elementAt(i);
			VarInt[] x = c.getVariables();
			if(x != null){
				for(int j = 0; j < x.length; j++)
					V.add(x[j]);
				
			}
			BasicLocalSearchEntity e = (BasicLocalSearchEntity)c;
			_Se[i] = e;
		}
		_vars  = new VarInt[V.size()];
		int i = -1;
		Iterator it = V.iterator();
		while(it.hasNext()){
			VarInt xi = (VarInt)it.next();
			i++;
			_vars[i] = xi;
		}		
		//initPropagate();
	}
	
	public void post(IConstraint c){
		_S.add(c);
	}
	
	public boolean verify(){
		for(int i = 0; i < _S.size(); i++)
			if(!_S.elementAt(i).verify())
				return false;
		return true;
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}
